package doublelinkedlist

import "fmt"

/**
 * 双向链表节点
 */
type DoubleListNode struct {
	prev  *DoubleListNode
	next  *DoubleListNode
	value interface{}
}

/**
 * 双向链表
 */
type DoubleLinkedList struct {
	head   *DoubleListNode
	tail   *DoubleListNode
	length int
}

// 获取头结点
func (this *DoubleLinkedList) GetHead() *DoubleListNode {
	return this.head
}

// 获取尾结点
func (this *DoubleLinkedList) GetTail() *DoubleListNode {
	return this.tail
}

// 获取前一个节点
func (this *DoubleListNode) GetPrev() *DoubleListNode {
	return this.prev
}

// 获取后一个节点
func (this *DoubleListNode) GetNext() *DoubleListNode {
	return this.next
}

// 获取链表的长度
func (this *DoubleLinkedList) GetLength() interface{} {
	return this.length
}

// 获取节点的值
func (this *DoubleListNode) GetValue() interface{} {
	return this.value
}

/**
 * 初始化节点
 */
func NewDoubleListNode(v interface{}) *DoubleListNode {
	return &DoubleListNode{nil, nil, v}
}

/**
 * 初始化链表
 */
func NewDoubleLinkedList() *DoubleLinkedList {
	linked := &DoubleLinkedList{NewDoubleListNode(0), NewDoubleListNode(0), 0}
	linked.head.next = linked.tail
	linked.tail.prev = linked.head
	return linked
}

// 在链表头部添加节点
func (this *DoubleLinkedList) InsertToHead(v interface{}) bool {
	return this.InsertAfter(this.head, v)
}

// 在链表尾部添加节点
func (this *DoubleLinkedList) InsertToTail(v interface{}) bool {
	return this.InsertBefore(this.tail, v)
}

// 在某个节点前添加节点
func (this *DoubleLinkedList) InsertBefore(p *DoubleListNode, v interface{}) bool {
	if nil == p {
		return false
	}

	// 初始化节点
	newNode := NewDoubleListNode(v)

	newNode.next = p
	newNode.prev = p.prev

	p.prev.next = newNode
	p.prev = newNode
	this.length++
	return true
}

// 在某个节点后添加节点
func (this *DoubleLinkedList) InsertAfter(p *DoubleListNode, v interface{}) bool {
	if nil == p {
		return false
	}

	newNode := NewDoubleListNode(v)

	newNode.next = p.next
	newNode.prev = p.next.prev

	p.next.prev = newNode
	p.next = newNode
	this.length++
	return true
}

// 删除节点
func (this *DoubleLinkedList) DeleteDoubleListNode(p *DoubleListNode) bool {
	if nil == p || this.tail == p {
		return false
	}

	p.prev.next = p.next
	p.next.prev = p.prev
	this.length--
	return true
}

// 正序打印列表
func (this *DoubleLinkedList) PrintDoubleLinkedListAsort() {
	for cur := this.head.next; cur != this.tail; cur = cur.next {
		fmt.Printf("%+v", cur.value)
		if cur.next != this.tail {
			fmt.Printf("->")
		}
	}
	fmt.Println()
}

// 倒序打印列表
func (this *DoubleLinkedList) PrintDoubleLinkedListRsort() {
	for cur := this.tail.prev; cur != this.head; cur = cur.prev {
		fmt.Printf("%+v", cur.value)
		if cur.prev != this.head {
			fmt.Printf("->")
		}
	}
	fmt.Println()
}
